﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace OF.Utility
{
    /// <summary>
    /// 一些有意思的扩展方法
    /// </summary>
    public static class FancyExtensions
    {
        #region 链式编程
        /**//// <summary>
            /// 先执行操作，再返回自身,链接编程包装函数
            /// </summary>
        public static T Do<T>(this T t, Action<T> action)
        {
            action(t);
            return t;
        }
        #endregion

        #region WhereIf扩展
        //return source
        //.WhereIf(p => p.Name.Contains(name), string.IsNullOrEmpty(name) == false)
        //.WhereIf(p => p.Code.Contains(code), string.IsNullOrEmpty(code) == false)
        //.WhereIf(p => p.Code.Contains(address), string.IsNullOrEmpty(address) == false);
        public static IQueryable<T> WhereIf<T>(this IQueryable<T> source, Expression<Func<T, bool>> predicate, bool condition)
        {
            return condition ? source.Where(predicate) : source;
        }
        public static IQueryable<T> WhereIf<T>(this IQueryable<T> source, Expression<Func<T, int, bool>> predicate, bool condition)
        {
            return condition ? source.Where(predicate) : source;
        }
        public static IEnumerable<T> WhereIf<T>(this IEnumerable<T> source, Func<T, bool> predicate, bool condition)
        {
            return condition ? source.Where(predicate) : source;
        }
        public static IEnumerable<T> WhereIf<T>(this IEnumerable<T> source, Func<T, int, bool> predicate, bool condition)
        {
            return condition ? source.Where(predicate) : source;
        }
        #endregion

        #region if扩展
        //int int0 = -121;
        //int int1 = int0.If(i => i < 0, i => -i)
        //    .If(i => i > 100, i => i - 100)
        //    .If(i => i % 2 == 1, i => i - 1);
        /// <summary>
        /// /
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <param name="predicate"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        public static T If<T>(this T t, Predicate<T> predicate, Func<T, T> func) where T : struct
        {
            return predicate(t) ? func(t) : t;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <param name="predicate"></param>
        /// <param name="actions"></param>
        /// <returns></returns>
        public static T If<T>(this T t, Predicate<T> predicate, params Action<T>[] actions) where T : class
        {
            if (t == null) throw new ArgumentNullException();
            if (predicate(t))
            {
                foreach (var action in actions)
                    action(t);
            }
            return t;
        }
        ////从邮箱变换成主页
        //string email = "ldp615@163.com";
        //string page = email.If(s => s.Contains("@"), s => s.Substring(0, s.IndexOf("@")))
        //    .If(s => !s.StartsWith("www."), s => s = "www." + s)
        //    .If(s => !s.EndsWith(".com"), s => s += ".com");
        /// <summary>
        /// string的If扩展方法
        /// </summary>
        /// <param name="s"></param>
        /// <param name="predicate"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        public static string If(this string s, Predicate<string> predicate, Func<string, string> func)
        {
            return predicate(s) ? func(s) : s;
        }
        #endregion

        #region switch扩展
        //string englishName = "apple";
        //string chineseName = englishName.Switch(
        //    new string[] { "apple", "orange", "banana", "pear" },
        //    new string[] { "苹果", "桔子", "香蕉", "梨" },
        //    "未知"
        //    );
        //Console.WriteLine(chineseName);
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TOutput"></typeparam>
        /// <typeparam name="TInput"></typeparam>
        /// <param name="input"></param>
        /// <param name="inputSource"></param>
        /// <param name="outputSource"></param>
        /// <param name="defaultOutput"></param>
        /// <returns></returns>
        public static TOutput Switch<TOutput, TInput>(this TInput input, IEnumerable<TInput> inputSource, IEnumerable<TOutput> outputSource, TOutput defaultOutput)
        {
            IEnumerator<TInput> inputIterator = inputSource.GetEnumerator();
            IEnumerator<TOutput> outputIterator = outputSource.GetEnumerator();

            TOutput result = defaultOutput;
            while (inputIterator.MoveNext())
            {
                if (outputIterator.MoveNext())
                {
                    if (input.Equals(inputIterator.Current))
                    {
                        result = outputIterator.Current;
                        break;
                    }
                }
                else break;
            }
            return result;
        }
        #endregion


    }
}
